package com.zhong.encrypt.Utils;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESUtil {

    /**
     * 生产秘钥
     * @param seed 种子
     * @return the secretKey
     * @throws Exception
     */
    public static SecretKey generateKey(String seed) throws Exception {
        // 获取秘钥生成器
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        // 通过种子初始化
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.setSeed(seed.getBytes("UTF-8"));
        //AES-128
        keyGenerator.init(128, secureRandom);
        // 生成秘钥并返回
        return keyGenerator.generateKey();
    }

    /**
     * 用秘钥进行加密
     * @param content   明文
     * @param secretKey 秘钥
     * @return byte数组的密文
     * @throws Exception
     */
    public static byte[] encrypt(String content, SecretKey secretKey) throws Exception {
        // 秘钥
        byte[] enCodeFormat = secretKey.getEncoded();
        return encrypt(content, enCodeFormat);
    }

    /**
     * 用秘钥进行加密
     * @param content   明文
     * @param secretKeyEncoded 秘钥Encoded
     * @return byte数组的密文
     * @throws Exception
     */
    public static byte[] encrypt(String content, byte[] secretKeyEncoded) throws Exception {
        // 创建AES秘钥
        SecretKeySpec key = new SecretKeySpec(secretKeyEncoded, "AES");
        // 创建密码器
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//        Cipher cipher = Cipher.getInstance("AES");
        // 初始化加密器
        cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(new byte[cipher.getBlockSize()]));
        // 加密
        return cipher.doFinal(content.getBytes("UTF-8"));
    }


    /**
     * 用秘钥进行加密返回16进制字符串
     * @param content      明文
     * @param secretKey    秘钥
     * @return 密文的16进制字符串
     * @throws Exception
     */
    public static String encryptToHex(String content, SecretKey secretKey) throws Exception {
        byte[] result = encrypt(content, secretKey);
        return HexUtil.encode(result);
    }

    /**
     * 用秘钥进行加密返回16进制字符串
     * @param content      明文
     * @param secretKeyEncoded    秘钥
     * @return 密文的16进制字符串
     * @throws Exception
     */
    public static String encryptToHex(String content, byte[] secretKeyEncoded) throws Exception {
        byte[] result = encrypt(content, secretKeyEncoded);
        return HexUtil.encode(result);
    }

    /**
     * 解密
     * @param content   密文
     * @param secretKeyEncoded 秘钥
     * @return 解密后的明文
     * @throws Exception
     */
    public static byte[] decrypt(byte[] content, byte[] secretKeyEncoded) throws Exception {
        // 创建AES秘钥
        SecretKeySpec key = new SecretKeySpec(secretKeyEncoded, "AES");
        // 创建密码器
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        // 初始化解密器
        cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(new byte[cipher.getBlockSize()]));
        // 解密
        return cipher.doFinal(content);
    }

    /**
     * 解密
     * @param content   密文
     * @param secretKey 秘钥
     * @return 解密后的明文
     * @throws Exception
     */
    public static byte[] decrypt(byte[] content, SecretKey secretKey) throws Exception {
        // 秘钥
        byte[] enCodeFormat = secretKey.getEncoded();
        return decrypt(content,enCodeFormat);
    }

    /**
     * 解密返回16进制数
     * @param content
     * @param secretKey
     * @return
     * @throws Exception
     */
    public static String decryptToStr(byte[] content, SecretKey secretKey) throws Exception {
        byte[] result = decrypt(content, secretKey);
        return new String(result);
    }

    /**
     * 解密返回String
     * @param content
     * @param secretKeyEncoded
     * @return
     * @throws Exception
     */
    public static String decryptToStr(byte[] content, byte[] secretKeyEncoded) throws Exception {
        byte[] result = decrypt(content, secretKeyEncoded);
        return new String(result);
    }
}
